import java.math.BigInteger;

/**
 * @author by zyl
 * @date 2020/3/28.
 */
public class Agreement {
    private static ECPoint P;
    private static ECPoint PK;
    private static ECCOperator ec;

    static {
        ec=new ECCOperator();
        ECPoint G=new ECPoint(new BigInteger("2"),new BigInteger("4"));
        P=ec.multiply(G,new BigInteger("123456"));
        String sPK= FileUtil.readTag(CommonValue.KeyTable,"KGC").split(" ")[1];
        PK=new ECPoint(new BigInteger(sPK.split(",")[0]),new BigInteger(sPK.split(",")[1]));
    }

    public static void agreement(){
        String ij=SocketUtils.in(CommonValue.C_A_PORT);
        System.out.println("Receiving ij from C:"+ij);
        BigInteger a=new BigInteger(CharacterUtils.getRandomInteger(16));
        System.out.println("Selects a random a:"+a);
        ECPoint Xa=ec.multiply(P,a);
        System.out.println("Computing Xa:"+Xa.toString());
        String RA=CharacterUtils.getRandomInteger(16);
        System.out.println("Computing RA:"+RA);
        String IDA=FileUtil.readTag(CommonValue.IDTable,"A").split(" ")[1];
        String KBi=FileUtil.readTag(CommonValue.KeyTable,"B1").split(" ")[1];
        String KCij=FileUtil.readTag(CommonValue.KeyTable,"C11").split(" ")[1];
        String IDB=FileUtil.readTag(CommonValue.IDTable,"B1").split(" ")[1];
        String IDC=FileUtil.readTag(CommonValue.IDTable,"C11").split(" ")[1];
        System.out.println("Choose KBi KCij IDBi IDCij:"+KBi+","+KCij+","+IDB+","+IDC);
        String HAB=HashUtils.Hash(RA+KBi+IDB);
        System.out.println("Computing HAB:"+HAB);
        String linkData1=Xa.toString()+":"+IDA+":"+KCij+":"+IDC+":"+RA;
        String Ea=Base64.encode(XorUtils.xor(linkData1,HAB));
        System.out.println("Computing Ea:"+Ea);
        String ToB=Ea+":"+RA;
        System.out.println("Sending Ea RA to B:"+ToB);
        SocketUtils.out(CommonValue.A_B_IP,CommonValue.A_B_Port,ToB);
        String fromB=SocketUtils.in(CommonValue.B_A_Port);
        System.out.println("Receiving fromB:"+fromB);
        String Eba=fromB.split(":")[0];
        String RB=fromB.split(":")[1];

        String Eba_=Base64.decode(Eba);
        String linkData2=XorUtils.xor(Eba_,HAB);
        String xuIDA=linkData2.split(":")[0];
        System.out.println("Decoding xuIDA:"+xuIDA);
        String xuIDB=linkData2.split(":")[1];
        System.out.println("Decoding xuIDB:"+xuIDB);
        String xuIDC=linkData2.split(":")[2];
        System.out.println("Decoding xuIDC:"+xuIDC);
        String xXa=linkData2.split(":")[3];
        System.out.println("Decoding xXa:"+xXa);
        String xXc=linkData2.split(":")[4];
        System.out.println("Decoding xXc:"+xXc);
        String xVB=linkData2.split(":")[5];
        System.out.println("Decoding xVB:"+xVB);
        String RA1=CharacterUtils.getRandomInteger(16);
        System.out.println("Generating RA1:"+RA1);
        String xxVB=HashUtils.Hash(IDA+xuIDB+xuIDC+RB);
        System.out.println("Computing xxVB:"+xxVB);
        if(IDA.equals(xuIDA)&&xxVB.equals(xVB)){
            System.out.println("A Verifies B success!");
        }
        else{
            System.out.println("A Verifies B failed!");
        }
        String xcx=xXc.split(",")[0];
        String xcy=xXc.split(",")[1];
        ECPoint XXC=new ECPoint(new BigInteger(xcx),new BigInteger(xcy));
        ECPoint aXc=ec.multiply(XXC,a);
        String SSKAC=HashUtils.Hash(Xa.toString()+xXc+aXc.toString());
        System.out.println("SSKAC:"+SSKAC);
        String HAC=HashUtils.Hash(IDA+xuIDB+xuIDC+SSKAC);
        System.out.println("HAC:"+HAC);
        String aToC=HAC+":"+RA1;
        SocketUtils.out(CommonValue.A_C_IP,CommonValue.A_C_PORT,aToC);
        String fromC=SocketUtils.in(CommonValue.C_A_PORT);
        String HCA=fromC.split(":")[0];
        String RC1=fromC.split(":")[1];
        System.out.println("receiving HCA:"+HCA);
        System.out.println("receiving RC1:"+RC1);
        if(HAC.equals(HCA)){
            System.out.println("A verifies C success!");
        }
        else{
            System.out.println("A verifies C failed!");
        }

    }

    public static void main(String args[]){
        agreement();
    }



}